﻿using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Ym.Core.Communi
{
    public class SerialPortService
    {
        SerialPort serialPort = new SerialPort();

        public SerialPortService(SerialPortParameter portParameter)
        {
            this.PortParameter = portParameter;
        }


        public SerialPortParameter PortParameter { get; private set; }

        public void Open()
        {
            if (serialPort.IsOpen)
            {
                return;
            }
            serialPort.PortName = PortParameter.PortName;
            serialPort.BaudRate = PortParameter.BaudRate;
            serialPort.Parity = PortParameter.Parity;
            serialPort.DataBits = PortParameter.DataBits;
            serialPort.StopBits = PortParameter.StopBits;
            serialPort.RtsEnable = true;
            serialPort.Open();
        }

        public void ReOpen()
        {
            Close();
            Open();
        }

        public void Close()
        {
            if (serialPort.IsOpen)
            {
                serialPort.Close();
            }
        }

        public void Write(byte[] datas)
        {
            WriteRead(datas, 0, false);
        }

        public byte[] WriteRead(byte[] datas, int millisecondsTimeout)
        {
            return WriteRead(datas, millisecondsTimeout, true);
        }

        byte[] WriteRead(byte[] datas, int millisecondsTimeout, bool isRead)
        {
            bool isNeedOpen = !serialPort.IsOpen;
            if (isNeedOpen)
            {
                Open();
            }
            try
            {
                DiscardBuffer();

                serialPort.Write(datas, 0, datas.Length);
                if (isRead)
                {
                    Thread.Sleep(millisecondsTimeout);
                    var result = new byte[serialPort.BytesToRead];
                    var ret = serialPort.Read(result, 0, result.Length);
                    return result;
                }
                return new byte[0];
            }
            finally
            {
                if (isNeedOpen)
                {
                    Close();
                }
            }

        }


        void DiscardBuffer()
        {
            serialPort.DiscardInBuffer();
            serialPort.DiscardOutBuffer();
        }
    }
}
